home *** CD-ROM | disk | FTP | other *** search
- /****
- ** 5/26/96
- ** shadow-adduser 1.5:
- **
- ** Just made it ask for your password twice.
- **
- ** David L Robinson
- ** drobinso@nrg.com.au
- **
- ** 6/27/95
- ** shadow-adduser 1.4:
- **
- ** now it copies the /etc/skel dir into the person's dir,
- ** makes the mail folders, changed some defaults and made a 'make
- ** install' just for the hell of it.
- **
- ** Greg Gallagher
- ** CIN.Net
- **
- ** 1/28/95
- ** shadow-adduser 1.3:
- **
- ** Basically a bug-fix on my additions in 1.2. Thanx to Terry Stewart
- ** (stew@texas.net) for pointing out one of the many idiotic bugs I introduced.
- ** It was such a stupid bug that I would have never seen it myself.
- **
- ** Brandon
- *****
- ** 01/27/95
- **
- ** shadow-adduser 1.2:
- ** I took the C source from adduser-shadow (credits are below) and made
- ** it a little more worthwhile. Many small changes... Here's
- ** the ones I can remember:
- **
- ** Removed support for non-shadowed systems (if you don't have shadow,
- ** use the original adduser, don't get this shadow version!)
- ** Added support for the correct /etc/shadow fields (Min days before
- ** password change, max days before password change, Warning days,
- ** and how many days from expiry date does the account go invalid)
- ** The previous version just left all of those fields blank.
- ** There is still one field left (expiry date for the account, period)
- ** which I have left blank because I do not use it and didn't want to
- ** spend any more time on this. I'm sure someone will put it in and
- ** tack another plethora of credits on here. :)
- ** Added in the password date field, which should always reflect the last
- ** date the password was changed, for expiry purposes. "passwd" always
- ** updates this field, so the adduser program should set it up right
- ** initially (or a user could keep thier initial password forever ;)
- ** The number is in days since Jan 1st, 1970.
- **
- ** Have fun with it, and someone please make
- ** a real version(this is still just a hack)
- ** for us all to use (and Email it to me???)
- **
- ** Brandon
- ** photon@usis.com
- **
- *****
- ** adduser 1.0: add a new user account (For systems not using shadow)
- ** With a nice little interface and a will to do all the work for you.
- **
- ** Craig Hagan
- ** hagan@opine.cs.umass.edu
- **
- ** Modified to really work, look clean, and find unused uid by Chris Cappuccio
- ** chris@slinky.cs.umass.edu
- **
- *****
- **
- ** 01/19/95
- **
- ** FURTHER modifications to enable shadow passwd support (kludged, but
- ** no more so than the original) by Dan Crowson - dcrowson@mo.net
- **
- ** Search on DAN for all changes...
- **
- *****
- **
- ** cc -O -o adduser adduser.c
- ** Use gcc if you have it... (political reasons beyond my control) (chris)
- **
- ** I've gotten this program to work with success under Linux (without
- ** shadow) and SunOS 4.1.3. I would assume it should work pretty well
- ** on any system that uses no shadow. (chris)
- **
- ** If you have no crypt() then try
- ** cc -DNO_CRYPT -O -o adduser adduser.c xfdes.c
- ** I'm not sure how login operates with no crypt()... I guess
- ** the same way we're doing it here.
- */
-
- #include <pwd.h>
- #include <grp.h>
- #include <ctype.h>
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
- #include <time.h>
- #include <sys/types.h>
- #include <sys/timeb.h>
- #include <sys/time.h>
- #include <sys/stat.h>
-
- #define PASSWD_FILE "/etc/passwd"
-
- #define SHADOW_FILE "/etc/shadow"
-
- #define DEFAULT_SHELL "/bin/bash" /* because BASH is your friend */
- #define DEFAULT_HOME "/home"
-
- #define DEFAULT_GROUP 100
-
- #define FIRST 500
-
- #define DEFAULT_PERMS 0700 /* Perms for the users home directory */
-
- #define DEFAULT_MIN_PASS 0
- #define DEFAULT_MAX_PASS 30
- #define DEFAULT_WARN_PASS 15
- #define DEFAULT_USER_DIE 10
-
- int unused_uid,nag;
- char *crypt();
-
- main()
- {
- char foo[32];
-
- char uname[9],person[32],dir[32],shell[32],salt[2];
-
- char *passwd;
-
- char *passwdone;
-
- char *passwdtwo;
-
- char tmp[255];
-
- char commandbuf[80];
-
- char cogusbuf[12];
-
- char *strd(char *s) {
- char *d;
- d=(char *)malloc(strlen(s) + 1);
- strcpy(d,s);
- return(d);
- }
-
-
- unsigned int group,uid,pass_change_date,min_pass,max_pass,warn_pass,user_die;
-
- /* the group and uid of the new user */
-
- int bad=0,done=0,correct=0,gets_warning=0,perfect=0;
-
- /* flags, in order:
- * bad to see if the username is in /etc/passwd, or if strange stuff has
- * been typed if the user might be put in group 0
- * done allows the program to exit when a user has been added
- * correct loops until a password is found that isn't in /etc/passwd
- * gets_warning allows the fflush to be skipped for the first gets
- * so that output is still legible
- */
-
- time_t tm;
-
- struct passwd *pw;
-
- FILE *passwd_file; /* Yep, it's a file allright */
-
- FILE *shadow_file;
-
- /* set unused uid to FIRST (#defined above) so that find_unused picks
- * a uid over FIRST (assuming we do everything else right :)
- */
-
- unused_uid = FIRST;
-
- /* The real program starts HERE! */
-
- /* Smile, it's the 2nd best thing you can do with your lips */
-
- /* Lesse if we know what we're doing here... */
-
- if(geteuid()!=0)
- {
- printf("It seems you don't have access to add a new user. Try\n");
- printf("logging in as root or su root to gain super-user access.\n");
- exit(1);
- }
-
- /* We don't support shadow password files, let's check and make
- * sure we're not using em. Sure we could use filesearch or something
- * but i don't feel like it.
- */
-
- while(!correct) /* loop until a "good" uname is chosen */
- { /* good = not in /etc/passwd */
- while(!done)
- {
- printf("\nUser to add (^C to quit): ");
-
- if(gets_warning) /* if the warning was already shown */
- fflush(stdout); /* fflush stdout, otherwise set the flag */
- else
- gets_warning=1;
-
- gets(uname);
-
- /* what I saw here before made me think maybe I was running DOS */
- /* might this be a solution? (chris) */
- if(nag=getpwnam(uname) != NULL)
- {
- printf("That name is in use, choose another.\n");
- done=0;
- }
- else done=1;
- }
-
- /* all set, get the rest of the stuff */
-
- printf("\nEditing information for new user [%s]\n",uname);
-
- printf("\nFull Name: ",uname);
- gets(person);
-
- printf("GID [%d]: ",DEFAULT_GROUP);
- gets(foo);
- group=atoi(foo);
-
- if (group==0) /* You're not allowed to make root group users! */
- group=DEFAULT_GROUP;
-
- unused_uid = find_unused(++unused_uid); /* our k-eleet unused! */
-
- printf("\nUID [%d]: ",unused_uid);
- gets(foo);
- uid=atoi(foo);
-
- if(uid==0) /* this is how i detect if you just hit return. */
- uid=unused_uid;
- /* it may also disable you from making a root user, but
- * doesen't that sound more like a feature?
- */
-
- if((pw=getpwuid(uid))!=NULL) /* uhh. duhh. egh.. */
- {
- printf("\nWarning: UID [%d] is already in use, this would conflict with\n",uid);
- printf("who is already owns that user ID. [%s]'s UID has been reset to\n",uname);
- printf("the last unused UID: [%d].\n",unused_uid);
- uid=unused_uid;
- }
-
- fflush(stdin);
-
- printf("\nHome Directory [%s/%s]: ",DEFAULT_HOME,uname);
- fflush(stdout);
- gets(dir);
-
- if (!strcmp(dir,""))
- sprintf(dir,"%s/%s",DEFAULT_HOME,uname);
- fflush(stdin);
-
- printf("\nShell [%s]: ",DEFAULT_SHELL);
- fflush(stdout);
- gets(shell);
-
- if (!strcmp(shell,""))
- sprintf(shell,"%s",DEFAULT_SHELL);
-
- printf("\nMin. Password Change Days [%d]: ",DEFAULT_MIN_PASS);
- gets(foo);
- min_pass = atoi(foo);
- if (min_pass == 0)
- min_pass = DEFAULT_MIN_PASS;
-
- printf("\nMax. Password Change Days [%d]: ",DEFAULT_MAX_PASS);
- gets(foo);
- if (strlen(foo) > 1)
- max_pass = atoi(foo);
- else
- max_pass = DEFAULT_MAX_PASS;
-
- printf("\nPassword Warning Days [%d]: ",DEFAULT_WARN_PASS);
- gets(foo);
- warn_pass = atoi(foo);
- if (warn_pass == 0)
- warn_pass = DEFAULT_WARN_PASS;
-
- printf("\nDays after Password Expiry for Account Locking [%d]: ",DEFAULT_USER_DIE);
- gets(foo);
- user_die = atoi(foo);
- if (user_die == 0)
- user_die = DEFAULT_USER_DIE;
-
- while(!perfect) /* Sets up a loop until the password is entered correct twice */
- {
-
- passwd = strd(getpass("Password: "));
- if(strcmp(passwd,getpass("Retype Password: "))) {
- fprintf(stderr, "Sorry, They do not match.\n");
- perfect = 0;
- }
- else perfect = 1;
- }
-
- if (!strcmp(passwd,""))
- sprintf(passwd,"%s",uname);
- {
- time(&tm);
- salt[0] = (tm & 0x0f) + 'A';
- salt[1] = ((tm & 0xf0) >> 4) + 'a';
- }
-
- printf("\nInformation for new user [%s]:\n",uname);
- printf("Home directory: [%s] Shell: [%s]\n",dir,shell);
- printf("Password: [<hidden>] uid: [%d] gid: [%d]\n",uid,group);
- printf("MinPass: [%d] MaxPass: [%d] WarnPass: [%d] UserExpire: [%d]\n",min_pass,max_pass,warn_pass,user_die);
- printf("\nIs this correct? [y/N]: ");
- fflush(stdout);
- gets(foo);
-
- done=bad=correct=perfect=(foo[0]=='y'||foo[0]=='Y');
-
- if(bad!=1)
- printf("\nUser [%s] not added\n",uname);
- }
-
- /* Calculate days since Jan 1st, 1970 for pass_change_date */
-
- pass_change_date=(int)((time(NULL)/86400)-1);
-
- printf("\nAdding login [%s] and making directory [%s]\n",uname,dir);
- mkdir(dir,DEFAULT_PERMS);
-
- system("cp /etc/passwd /etc/passwd.OLD"); /* Let's have safe sex */
-
- sprintf(tmp, "cp %s %s.OLD", SHADOW_FILE, SHADOW_FILE);
- system(tmp);
-
- passwd_file=fopen(PASSWD_FILE,"a");
-
- shadow_file=fopen(SHADOW_FILE,"a");
-
- #ifdef NO_CRYPT
-
- fprintf(passwd_file,"%s:x:%d:%d:%s:%s:%s\n"
- ,uname,uid,group,person,dir,shell);
- fprintf(shadow_file,"%s:%s:%d:%d:%d:%d:%d::\n", uname, fcrypt(passwd, salt), pass_change_date, min_pass, max_pass, warn_pass, user_die);
-
- #else
-
- fprintf(passwd_file,"%s:x:%d:%d:%s:%s:%s\n"
- ,uname,uid,group,person,dir,shell);
- fprintf(shadow_file,"%s:%s:%d:%d:%d:%d:%d::\n", uname, crypt(passwd, salt), pass_change_date, min_pass, max_pass, warn_pass, user_die);
- #endif
-
- fflush(passwd_file);
- fclose(passwd_file);
-
- fflush(shadow_file);
- fclose(shadow_file);
-
- /* yes, I fixed uid and group being screwed around (chris) */
-
- /* make sure that they own their directory -- its kinda nice :) */
- /* chown(dir,uid,group); */
-
- /* These are the Slackware hacks, added by Patrick Volkerding 12/3/93 */
- /* ...and changed some more on Mon May 2 14:43:34 CDT 1994 */
-
- printf("\nAdding the files from the /etc/skel directory:\n");
- fflush(stdout);
-
- /* First, we "give" the /etc/skel directory to the new user: */
-
- sprintf(commandbuf,"chown --recursive %d.%d /etc/skel 2>/dev/null",uid,group);
- system(commandbuf);
-
- /* Then, we copy the files owned by the new user into the new user's
- home directory. This way, if there are already files in the user's home
- directory (say, from a backup), the ownership of those files won't be
- changed. Some say this is progress. ;^) */
-
- sprintf(commandbuf,"( cd /etc/skel ; cp -a --verbose . %s )",dir);
- system(commandbuf);
-
- /* It's useful to give the new home directory a current
- creation date rather than the one from /etc/skel. */
-
- sprintf(commandbuf,"touch %s",dir);
- system(commandbuf);
-
- /* Give this stuff back to root. By sure to put the uid/gid you want for
- the default ownership of /etc/skel into the line below if 0.0 isn't good.*/
-
- sprintf(commandbuf,"chown --recursive 0.0 /etc/skel 2> /dev/null");
- system(commandbuf);
- sprintf(commandbuf,"touch /var/spool/mail/%s",uname);
- system(commandbuf);
- sprintf(commandbuf,"chown %d.mail /var/spool/mail/%s",uid,uname);
- system(commandbuf);
- sprintf(commandbuf,"chmod 660 /var/spool/mail/%s",uname);
- system(commandbuf);
- printf("\n\n");
- fflush(stdout);
- /* End SlackHacks */
- }
- /* Here is our trade secret patented copyrighted code to find an unused UID */
-
- find_unused(begin)
- int begin;
- {
- int trial;
- struct passwd *pw;
- trial = begin - 1;
-
- printf("\nChecking for an available UID after %d\n",FIRST);
-
- while ((pw = getpwuid(++trial)) != NULL) ;
-
- printf("\nFirst unused uid is %d\n", trial);
-
- return(trial);
- }
-
-